home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 076-100 / disk_081 / icon / overview.doc < prev    next >
Text File  |  1992-05-06  |  28KB  |  991 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.                    An Overview of the Icon Programming
  15.                                 Language*
  16.  
  17.  
  18.                             Ralph E. Griswold
  19.  
  20.  
  21.  
  22.  
  23.                                 TR 83-3c
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.                  May 13, 1983; last revised May 1, 1986
  50.  
  51.  
  52.                      Department of Computer Science
  53.  
  54.                         The University of Arizona
  55.  
  56.                           Tucson, Arizona 85721
  57.  
  58.  
  59.  
  60.  
  61.     *This work was supported by the National Science Foundation under
  62.     Grant DCR-8401831.
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75.  
  76.                    An Overview of the Icon Programming
  77.                                 Language
  78.  
  79.  
  80.  
  81.  
  82.     _1_.___I_n_t_r_o_d_u_c_t_i_o_n
  83.  
  84.        Icon is a high-level programming language with extensive
  85.     facilities for processing strings and lists. Icon has several
  86.     novel features, including expressions that may produce sequences
  87.     of results, goal-directed evaluation that automatically searches
  88.     for a successful result, and string scanning that allows opera-
  89.     tions on strings to be formulated at a high conceptual level.
  90.  
  91.        Icon resembles SNOBOL4 [1] in its emphasis on high-level
  92.     string processing and a design philosophy that allows ease of
  93.     programming and short, concise programs. Like SNOBOL4, storage
  94.     allocation and garbage collection are automatic in Icon, and
  95.     there are few restrictions on the sizes of objects. Strings,
  96.     lists, and other structures are created during program execution
  97.     and their size does not need to be known when a program is writ-
  98.     ten.  Values are converted to expected types automatically; for
  99.     example, numeral strings read in as input can be used in numeri-
  100.     cal computations without explicit conversion.  Whereas SNOBOL4
  101.     has a pattern-matching facility that is separate from the rest of
  102.     the language, string scanning is integrated with the rest of the
  103.     language facilities in Icon.  Unlike SNOBOL4, Icon has an
  104.     expression-based syntax with reserved words; in appearance, Icon
  105.     programs resemble those of several other conventional programming
  106.     languages.
  107.  
  108.        Examples of the kinds of problems for which Icon is well
  109.     suited are:
  110.  
  111.          o+  text analysis, editing, and formatting
  112.  
  113.          o+  document preparation
  114.  
  115.          o+  symbolic mathematics
  116.  
  117.          o+  text generation
  118.  
  119.          o+  parsing and translation
  120.  
  121.          o+  data laundry
  122.  
  123.          o+  graph manipulation
  124.  
  125.        Version 6 of Icon, the most recent version, is implemented in
  126.     C [2]. There are UNIX* implementations for the Amdahl 580, the
  127.     __________________________
  128.     *UNIX is a trademark of AT&T Bell Laboratories.
  129.  
  130.                                   - 1 -
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.     AT&T 3B series, the HP 9000, the IBM PC/XT/AT, the PDP-11, the
  140.     Ridge 32, the Sun Workstation, and the VAX-11.  There also is a
  141.     VMS implementation for the VAX-11 and a DOS implementation for
  142.     personal computers. Other implementations are in progress.
  143.  
  144.        A brief description of some of the representative features of
  145.     Icon is given in the following sections. This description is not
  146.     rigorous and does not include many features of Icon. See [3] for
  147.     a complete description and [4] for a description of recent
  148.     changes to the language.
  149.  
  150.  
  151.     _2_.___S_t_r_i_n_g_s
  152.  
  153.        Strings of characters may be arbitrarily long, limited only by
  154.     the architecture of the computer on which Icon is implemented. A
  155.     string may be specified literally by enclosing it in double quo-
  156.     tation marks, as in
  157.  
  158.             greeting := "Hello world"
  159.  
  160.     which assigns an 11-character string to greeting, and
  161.  
  162.             address := ""
  163.  
  164.     which assigns the zero-length _e_m_p_t_y string to address.  The
  165.     number of characters in a string s, its size, is given by *s. For
  166.     example, *greeting is 11 and *address is 0.
  167.  
  168.        Icon uses the ASCII character set, extended to 256 characters.
  169.     There are escape conventions, similar to those of C, for
  170.     representing characters that cannot be keyboarded.
  171.  
  172.        Strings also can be read in and written out, as in
  173.  
  174.             line := read()
  175.  
  176.     and
  177.  
  178.             write(line)
  179.  
  180.     Strings can be constructed by concatenation, as in
  181.  
  182.             element := "(" || read() || ")"
  183.  
  184.     If the concatenation of a number of strings is to be written out,
  185.     the write function can be used with several arguments to avoid
  186.     actual concatenation:
  187.  
  188.             write("(",read(),")")
  189.  
  190.  
  191.        Substrings can be formed by subscripting strings with range
  192.     specifications that indicate, by position, the desired range of
  193.  
  194.  
  195.  
  196.                                   - 2 -
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.     characters. For example,
  206.  
  207.             middle := line[10:20]
  208.  
  209.     assigns to middle the string of characters of line between posi-
  210.     tions 10 and 20.  Similarly,
  211.  
  212.             write(line[2])
  213.  
  214.     writes the second character of line.  The value 0 is used to
  215.     refer to the position after the last character of a string. Thus
  216.  
  217.             write(line[2:0])
  218.  
  219.     writes the substring of line from the second character to the
  220.     end, thus omitting the first character.
  221.  
  222.        An assignment can be made to the substring of string-valued
  223.     variable to change its value. For example,
  224.  
  225.             line[2] := "..."
  226.  
  227.     replaces the second character of line by three dots. Note that
  228.     the size of line changes automatically.
  229.  
  230.        There are many functions for analyzing strings. An example is
  231.  
  232.             find(s1,s2)
  233.  
  234.     which produces the position in s2 at which s1 occurs as a sub-
  235.     string. For example, if the value of greeting is as given ear-
  236.     lier,
  237.  
  238.             find("or",greeting)
  239.  
  240.     produces the value 8.  See Section 4.2 for the handling of situa-
  241.     tions in which s1 does not occur in s2, or in which it occurs at
  242.     several different positions.
  243.  
  244.  
  245.     _3_.___C_h_a_r_a_c_t_e_r__S_e_t_s
  246.  
  247.        While strings are sequences of characters, _c_s_e_t_s are sets of
  248.     characters in which membership rather than order is significant.
  249.     Csets are represented literally using single enclosing quotation
  250.     marks, as in
  251.  
  252.             vowels := 'aeiouAEIOU'
  253.  
  254.     Two useful built-in csets are &lcase and &ucase, which consist of
  255.     the lowercase and uppercase letters, respectively.  Set opera-
  256.     tions are provided for csets. For example,
  257.  
  258.  
  259.  
  260.  
  261.  
  262.                                   - 3 -
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.             letters := &lcase ++ &ucase
  272.  
  273.     forms the cset union of the lowercase and uppercase letters and
  274.     assigns the resulting cset to letters, while
  275.  
  276.             consonants := letters -- 'aeiouAEIOU'
  277.  
  278.     forms the cset difference of the letters and the vowels and
  279.     assigns the resulting cset to consonants.
  280.  
  281.        Csets are useful in situations in which any one of a number of
  282.     characters is significant. An example is the string analysis
  283.     function
  284.  
  285.             upto(c,s)
  286.  
  287.     which produces the position s at which any character in c occurs.
  288.     For example,
  289.  
  290.             upto(vowels,greeting)
  291.  
  292.     produces 2. Another string analysis function that uses csets is
  293.  
  294.             many(c,s)
  295.  
  296.     which produces the position in s after an initial substring con-
  297.     sisting only of characters that occur in s.  An example of the
  298.     use of many is in locating words. Suppose, for example, that a
  299.     word is defined to consist of a string of letters.  The expres-
  300.     sion
  301.  
  302.             write(line[1:many(letters,line)])
  303.  
  304.     writes a word at the beginning of line. Note the use of the posi-
  305.     tion returned by a string analysis function to specify the end of
  306.     a substring.
  307.  
  308.  
  309.     _4_.___E_x_p_r_e_s_s_i_o_n__E_v_a_l_u_a_t_i_o_n
  310.  
  311.     _4_._1___C_o_n_d_i_t_i_o_n_a_l__E_x_p_r_e_s_s_i_o_n_s
  312.  
  313.        In Icon there are _c_o_n_d_i_t_i_o_n_a_l _e_x_p_r_e_s_s_i_o_n_s that may _s_u_c_c_e_e_d and
  314.     produce a result, or may _f_a_i_l and not produce any result. An
  315.     example is the comparison operation
  316.  
  317.             i > j
  318.  
  319.     which succeeds (and produces the value of j) provided that the
  320.     value of i is greater than the value of j, but fails otherwise.
  321.  
  322.        The success or failure of conditional operations is used
  323.     instead of Boolean values to drive control structures in Icon. An
  324.     example is
  325.  
  326.  
  327.  
  328.                                   - 4 -
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337.             if i > j then k := i else k := j
  338.  
  339.     which assigns the value of i to k if the value of i is greater
  340.     than the value of j, but assigns the value of j to k otherwise.
  341.  
  342.        The usefulness of the concepts of success and failure is
  343.     illustrated by find(s1,s2), which fails if s1 does not occur as a
  344.     substring of s2.  Thus
  345.  
  346.             if i := find("or",line) then write(i)
  347.  
  348.     writes the position at which or occurs in line, if it occurs, but
  349.     does not write a value if it does not occur.
  350.  
  351.        Many expressions in Icon are conditional. An example is
  352.     read(), which produces the next line from the input file, but
  353.     fails when the end of the file is reached. The following expres-
  354.     sion is typical of programming in Icon and illustrates the
  355.     integration of conditional expressions and conventional control
  356.     structures:
  357.  
  358.             while line := read() do
  359.                write(line)
  360.  
  361.     This expression copies the input file to the output file.
  362.  
  363.        If an argument of a function fails, the function is not
  364.     called, and the function call fails as well. This ``inheritance''
  365.     of failure allows the concise formulation of many programming
  366.     tasks. Omitting the optional do clause in while-do, the previous
  367.     expression can be rewritten as
  368.  
  369.             while write(read())
  370.  
  371.  
  372.     _4_._2___G_e_n_e_r_a_t_o_r_s
  373.  
  374.        In some situations, an expression may be capable of producing
  375.     more than one result. Consider
  376.  
  377.             sentence := "Store it in the neighboring harbor"
  378.             find("or",sentence)
  379.  
  380.     Here or occurs in sentence at positions 3, 23, and 33. Most pro-
  381.     gramming languages treat this situation by selecting one of the
  382.     positions, such as the first, as the result of the expression. In
  383.     Icon, such an expression is a _g_e_n_e_r_a_t_o_r and is capable of produc-
  384.     ing all three positions.
  385.  
  386.        The results that a generator produces depend on context. In a
  387.     situation where only one result is needed, the first is produced,
  388.     as in
  389.  
  390.  
  391.  
  392.  
  393.  
  394.                                   - 5 -
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.  
  403.             i := find("or",sentence)
  404.  
  405.     which assigns the value 3 to i.
  406.  
  407.        If the result produced by a generator does not lead to the
  408.     success of an enclosing expression, however, the generator is
  409.     _r_e_s_u_m_e_d to produce another value. An example is
  410.  
  411.             if (i := find("or",sentence)) > 5 then write(i)
  412.  
  413.     Here the first result produced by the generator, 3, is assigned
  414.     to i, but this value is not greater than 5 and the comparison
  415.     operation fails. At this point, the generator is resumed and pro-
  416.     duces the second position, 23, which is greater than 5. The com-
  417.     parison operation then succeeds and the value 23 is written.
  418.     Because of the inheritance of failure and the fact that com-
  419.     parison operations return the value of their right argument, this
  420.     expression can be written in the following more compact form:
  421.  
  422.             write(5 < find("or",sentence))
  423.  
  424.  
  425.        Goal-directed evaluation is inherent in the expression evalua-
  426.     tion mechanism of Icon and can be used in arbitrarily complicated
  427.     situations.  For example,
  428.  
  429.             find("or",sentence1) = find("and",sentence2)
  430.  
  431.     succeeds if or occurs in sentence1 at the same position as and
  432.     occurs in sentence2.
  433.  
  434.        A generator can be resumed repeatedly to produce all its
  435.     results by using the every-do control structure. An example is
  436.  
  437.             every i := find("or",sentence)
  438.                do write(i)
  439.  
  440.     which writes all the positions at which or occurs in sentence.
  441.     For the example above, these are 3, 23, and 33.
  442.  
  443.        Generation is inherited like failure, and this expression can
  444.     be written more concisely by omitting the optional do clause:
  445.  
  446.             every write(find("or",sentence))
  447.  
  448.  
  449.        There are several built-in generators in Icon. One of the most
  450.     frequently used of these is
  451.  
  452.             i to j
  453.  
  454.     which generates the integers from i to j. This generator can be
  455.     combined with every-do to formulate the traditional for-style
  456.     control structure:
  457.  
  458.  
  459.  
  460.                                   - 6 -
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.             every k := i to j do
  470.                f(k)
  471.  
  472.     Note that this expression can be written more compactly as
  473.  
  474.             every f(i to j)
  475.  
  476.  
  477.        There are a number of other control structures related to gen-
  478.     eration.  One is _a_l_t_e_r_n_a_t_i_o_n,
  479.  
  480.             _e_x_p_r_1 | _e_x_p_r_2
  481.  
  482.     which generates the results of _e_x_p_r_1 followed by the results of
  483.     _e_x_p_r_2.  Thus
  484.  
  485.             every write(find("or",sentence1) | find("or",sentence2))
  486.  
  487.     writes the positions of or in sentence1 followed by the positions
  488.     of or in sentence2. Again, this sentence can be written more com-
  489.     pactly by using alternation in the second argument of find:
  490.  
  491.             every write(find("or",sentence1 | sentence2))
  492.  
  493.  
  494.        Another use of alternation is illustrated by
  495.  
  496.             (i | j | k) = (0 | 1)
  497.  
  498.     which succeeds if any of i, j, or k has the value 0 or 1.
  499.  
  500.  
  501.     _5_.___S_t_r_i_n_g__S_c_a_n_n_i_n_g
  502.  
  503.        The string analysis and synthesis operations described in Sec-
  504.     tions 2 and 3 work best for relatively simple operations on
  505.     strings.  For complicated operations, the bookkeeping involved in
  506.     keeping track of positions in strings becomes burdensome and
  507.     error prone.  In such cases, Icon has a string scanning facility
  508.     that is analogous in many respects to pattern matching in SNO-
  509.     BOL4. In string scanning, positions are managed automatically and
  510.     attention is focused on a current position in a string as it is
  511.     examined by a sequence of operations.
  512.  
  513.        The string scanning operation has the form
  514.  
  515.             s ? _e_x_p_r
  516.  
  517.     where s is the _s_u_b_j_e_c_t string to be examined and _e_x_p_r is an
  518.     expression that performs the examination.  A position in the sub-
  519.     ject, which starts at 1, is the focus of examination.
  520.  
  521.        _M_a_t_c_h_i_n_g _f_u_n_c_t_i_o_n_s change this position.  One matching func-
  522.     tion, move(i), moves the position by i and produces the substring
  523.  
  524.  
  525.  
  526.                                   - 7 -
  527.  
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535.     of the subject between the previous and new positions. If the
  536.     position cannot be moved by the specified amount (because the
  537.     subject is not long enough), move(i) fails. A simple example is
  538.  
  539.             line ? while write(move(2))
  540.  
  541.     which writes successive two-character substrings of line, stop-
  542.     ping when there are no more characters.
  543.  
  544.        Another matching function is tab(i), which sets the position
  545.     in the subject to i and also returns the substring of the subject
  546.     between the previous and new positions.  For example,
  547.  
  548.             line ? if tab(10) then write(tab(0))
  549.  
  550.     first sets the position in the subject to 10 and then to the end
  551.     of the subject, writing line[10:0].  Note that no value is writ-
  552.     ten if the subject is not long enough.
  553.  
  554.        String analysis functions such as find can be used in string
  555.     scanning. In this context, the string that they operate on is not
  556.     specified and is taken to be the subject. For example,
  557.  
  558.             line ? while write(tab(find("or")))
  559.                do move(2)
  560.  
  561.     writes all the substrings of line prior to occurrences of or.
  562.     Note that find produces a position, which is then used by tab to
  563.     change the position and produce the desired substring. The
  564.     move(2) skips the or that is found.
  565.  
  566.        Another example of the use of string analysis functions in
  567.     scanning is
  568.  
  569.             line ? while tab(upto(letters)) do
  570.                write(tab(many(letters)))
  571.  
  572.     which writes all the words in line.
  573.  
  574.        As illustrated in the examples above, any expression may occur
  575.     in the scanning expression. Unlike SNOBOL4, in which the opera-
  576.     tions that are allowed in pattern matching are limited and
  577.     idiosyncratic, string scanning is completely integrated with the
  578.     rest of the operation repertoire of Icon.
  579.  
  580.  
  581.     _6_.___S_t_r_u_c_t_u_r_e_s
  582.  
  583.        Icon supports several kinds of structures with different
  584.     organizations and access methods. Lists are linear structures
  585.     that can be accessed both by position and by stack and queue
  586.     functions. Sets are collections of arbitrary values with no
  587.     implied ordering. Tables provide an associative lookup mechanism.
  588.  
  589.  
  590.  
  591.  
  592.                                   - 8 -
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600.  
  601.     _6_._1___L_i_s_t_s
  602.  
  603.        While strings are sequences of characters, lists in Icon are
  604.     sequences of values of arbitrary types. Lists are created by
  605.     enclosing the lists of values in brackets. An example is
  606.  
  607.             car1 := ["buick","skylark",1978,2450]
  608.  
  609.     in which the list car1 has four values, two of which are strings
  610.     and two of which are integers. Note that the values in a list
  611.     need not all be of the same type. In fact, any kind of value can
  612.     occur in a list - even another list, as in
  613.  
  614.             inventory := [car1,car2,car3,car4]
  615.  
  616.  
  617.        Lists also can be created by
  618.  
  619.             a := list(i,x)
  620.  
  621.     which creates a list of i values, each of which has the value x.
  622.  
  623.        The values in a list can be referenced by position much like
  624.     the characters in a string. Thus
  625.  
  626.             car1[4] := 2400
  627.  
  628.     changes the last value in car1 to 2400.  A reference that is out
  629.     of the range of the list fails. For example,
  630.  
  631.             write(car1[5])
  632.  
  633.     fails.
  634.  
  635.        The values in a list a are generated by !a. Thus
  636.  
  637.             every write(!a)
  638.  
  639.     writes all the values in a.
  640.  
  641.        Lists can be manipulated like stacks and queues. The function
  642.     push(a,x) adds the value of x to the left end of the list a,
  643.     automatically increasing the size of a by one. Similarly, pop(a)
  644.     removes the leftmost value from a, automatically decreasing the
  645.     size of a by one, and produces the removed value.
  646.  
  647.        A list value in Icon is a pointer (reference) to a structure.
  648.     Assignment of a structure in Icon does not copy the structure
  649.     itself but only the pointer to it. Thus the result of
  650.  
  651.             demo := car1
  652.  
  653.     causes demo and car1 to reference the same list. Graphs with
  654.     loops can be constructed in this way. For example,
  655.  
  656.  
  657.  
  658.                                   - 9 -
  659.  
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667.             node1 := ["a"]
  668.             node2 := [node1,"b"]
  669.             push(node1,node2)
  670.  
  671.     constructs a structure that can be pictured as follows:
  672.  
  673.  
  674.               node1  .->a--.
  675.                      |     |
  676.                      |     |
  677.               node2  '--b<-'
  678.  
  679.  
  680.  
  681.     _6_._2___S_e_t_s
  682.  
  683.        Sets are collections of values. A set is obtained from a list
  684.     by set(a), where a contains the members of the set. For example,
  685.  
  686.             s := set([1,"abc",[]])
  687.  
  688.     assigns to s a set that contains the integer 1, the string "abc",
  689.     and an empty list.
  690.  
  691.        The set operations of union, intersection, and difference are
  692.     provided.  The function member(s,x) succeeds if x is a member of
  693.     the set s but fails otherwise. The function insert(s,x) adds x to
  694.     the set s, while delete(s,x) removes x from s. A value only can
  695.     occur once in a set, so insert(s,x) has no effect if x is already
  696.     in s.
  697.  
  698.        The operation *s produces the number of members in s and !s
  699.     generates the members of s.
  700.  
  701.        A simple example of the use of sets is given by the following
  702.     segment of code, which lists all the different words that appear
  703.     in the input file:
  704.  
  705.             words := set([])
  706.             while line := read() do
  707.                line ? while tab(upto(letters)) do
  708.                   insert(words,tab(many(letters)))
  709.             every write(!words)
  710.  
  711.  
  712.     _6_._3___T_a_b_l_e_s
  713.  
  714.        Icon has a table data type similar to that of SNOBOL4. Tables
  715.     essentially are sets of pairs of values, an _e_n_t_r_y _v_a_l_u_e and a
  716.     corresponding _a_s_s_i_g_n_e_d _v_a_l_u_e. The entry and assigned values may
  717.     be of any type, and the assigned value for any entry value can be
  718.     looked up automatically.  Thus tables provide a form of associa-
  719.     tive access in contrast with the positional access to values in
  720.     lists.
  721.  
  722.  
  723.  
  724.                                  - 10 -
  725.  
  726.  
  727.  
  728.  
  729.  
  730.  
  731.  
  732.  
  733.        A table is created by an expression such as
  734.  
  735.             symbols := table(x)
  736.  
  737.     which assigns to symbols a table with the default assigned value
  738.     x.  Subsequently, symbols can be referenced by any entry value,
  739.     such as
  740.  
  741.             symbols["there"] := 1
  742.  
  743.     which assigns the value 1 to the thereth entry in symbols.
  744.  
  745.        Tables grow automatically as new entry values are added.  For
  746.     example, the following program segment produces a table contain-
  747.     ing a count of the words that appear in the input file:
  748.  
  749.             words := table(0)
  750.             while line := read() do
  751.                line ? while tab(upto(letters)) do
  752.                   words[tab(many(letters))] +:= 1
  753.  
  754.     Here the default assigned value for each word is 0, as given in
  755.     table(0), and +:= is an augmented assignment operation that
  756.     increments the assigned values by one.  There are augmented
  757.     assignment operations for all binary operators.
  758.  
  759.        A list can be obtained from a table by the function sort(t,1).
  760.     The form of the list depends on the value of i. For example, if i
  761.     is 3, the list contains alternate entry and assigned values of t.
  762.     For example,
  763.  
  764.             wordlist := sort(words,3)
  765.             while write(pop(wordlist)," : ",pop(wordlist))
  766.  
  767.     writes the words and their counts from words.
  768.  
  769.  
  770.     _7_.___P_r_o_c_e_d_u_r_e_s
  771.  
  772.        An Icon program consists of a sequence of procedure declara-
  773.     tions.  An example of a procedure declaration is
  774.  
  775.             procedure max(i,j)
  776.                if i > j then return i else return j
  777.             end
  778.  
  779.     where the name of the procedure is max and its formal parameters
  780.     are i and j. The return expressions return the value of i or j,
  781.     whichever is larger.
  782.  
  783.        Procedures are called like built-in functions. Thus
  784.  
  785.             k := max(*s1,*s2)
  786.  
  787.  
  788.  
  789.  
  790.                                  - 11 -
  791.  
  792.  
  793.  
  794.  
  795.  
  796.  
  797.  
  798.  
  799.     assigns to k the size of the longer of the strings s1 and s2.
  800.  
  801.        A procedure also may suspend instead of returning. In this
  802.     case, a result is produced as in the case of a return, but the
  803.     procedure can be resumed to produce other results. An example is
  804.     the following procedure that generates the words in the input
  805.     file.
  806.  
  807.             procedure genword()
  808.                local line, letters, words
  809.                letters := &lcase ++ &ucase
  810.                while line := read() do
  811.                   line ? while tab(upto(letters)) do {
  812.                      word := tab(many(letters))
  813.                      suspend word
  814.                      }
  815.             end
  816.  
  817.     The braces enclose a compound expression.
  818.  
  819.        Such a generator is used in the same way that a built-in gen-
  820.     erator is used. For example
  821.  
  822.             every word := genword() do
  823.                if find("or",word) then write(word)
  824.  
  825.     writes only those words that contain the substring or.
  826.  
  827.  
  828.     _8_.___A_n__E_x_a_m_p_l_e
  829.  
  830.        The following program sorts graphs topologically.
  831.  
  832.             procedure main()
  833.                local sorted, nodes, arcs, roots
  834.                while nodes := read() do {      # get next node list
  835.                   arcs := read()               # get arc list
  836.                   sorted := ""                 # sorted nodes
  837.                                                # get nodes without predecessors
  838.                   while *(roots := nodes -- snodes(arcs)) > 0 do {
  839.                      sorted ||:= roots         # add to sorted nodes
  840.                      nodes --:= roots          # delete these nodes
  841.                      arcs := delarcs(arcs,roots)# delete their arcs
  842.                      }
  843.                   if *arcs = 0 then write(sorted)# successfully sorted
  844.                   else write("graph has cycle")# cycle if node remains
  845.                }
  846.             end
  847.  
  848.  
  849.  
  850.  
  851.  
  852.  
  853.  
  854.  
  855.  
  856.                                  - 12 -
  857.  
  858.  
  859.  
  860.  
  861.  
  862.  
  863.  
  864.  
  865.             procedure snodes(arcs)
  866.                local nodes
  867.                nodes := ""
  868.                arcs ? while move(1) do {       # predecessor
  869.                   move(2)                      # skip "->"
  870.                   nodes ||:= move(1)           # successor
  871.                   move(1)                      # skip ";"
  872.                   }
  873.                return nodes
  874.             end
  875.  
  876.  
  877.             procedure delarcs(arcs,roots)
  878.                local newarcs, node
  879.                newarcs := ""
  880.                arcs ? while node := move(1) do {# get predecessor node
  881.                   if many(roots,node) then move(4)# delete arc from root node
  882.                   else newarcs ||:= node || move(4)# else keep arc
  883.                   }
  884.                return newarcs
  885.             end
  886.  
  887.     Graph nodes are represented by single characters with a list of
  888.     the nodes on one input line followed by a list of arcs. For exam-
  889.     ple, the graph
  890.  
  891.  
  892.                       .---------------.
  893.                       |               |
  894.                       |               v|
  895.                       a------>b------>c
  896.                       ^|       |       ^|
  897.                       |       |       |
  898.                       |       |v       |
  899.                       d------>e-------'
  900.  
  901.  
  902.     is given as
  903.  
  904.             abcde
  905.             a->b;a->c;b->c;b->e;d->a;d->e;e->c;
  906.  
  907.     for which the output is
  908.  
  909.             dabec
  910.  
  911.  
  912.        The nodes are represented by csets and automatic type conver-
  913.     sion is used to convert strings to csets and vice versa.  Note
  914.     the use of augmented assignment operations for concatenation and
  915.     in the computation of cset differences.
  916.  
  917.  
  918.  
  919.  
  920.  
  921.  
  922.                                  - 13 -
  923.  
  924.  
  925.  
  926.  
  927.  
  928.  
  929.  
  930.  
  931.     _A_c_k_n_o_w_l_e_d_g_e_m_e_n_t
  932.  
  933.        Icon was designed by the the author in collaboration with Dave
  934.     Hanson, Tim Korb, Cary Coutant, and Steve Wampler. The current
  935.     implementation is largely the work of Cary Coutant and Steve
  936.     Wampler with recent contributions by Bill Mitchell and Janalee
  937.     O'Bagy.  Dave Hanson and Bill Mitchell made several helpful
  938.     suggestions on the presentation of material in this paper.
  939.  
  940.     _R_e_f_e_r_e_n_c_e_s
  941.  
  942.  
  943.     1. Griswold, Ralph E., Poage, James F., and Polonsky, Ivan P.
  944.        _T_h_e _S_N_O_B_O_L_4 _P_r_o_g_r_a_m_m_i_n_g _L_a_n_g_u_a_g_e, second edition.  Prentice-
  945.        Hall, Inc., Englewood Cliffs, New Jersey. 1971.
  946.  
  947.     2. Kernighan, Brian W. and Ritchie, Dennis M. _T_h_e _C _P_r_o_g_r_a_m_m_i_n_g
  948.        _L_a_n_g_u_a_g_e. Prentice-Hall, Inc., Englewood Cliffs, New Jersey.
  949.        1978.
  950.  
  951.     3. Griswold, Ralph E. and Griswold, Madge T. _T_h_e _I_c_o_n _P_r_o_g_r_a_m_m_i_n_g
  952.        _L_a_n_g_u_a_g_e. Prentice-Hall, Inc., Englewood Cliffs, New Jersey.
  953.        1983.
  954.  
  955.     4. Griswold, Ralph E., and Mitchell, William H., and O'Bagy,
  956.        Janalee.  _V_e_r_s_i_o_n _6._0 _o_f _I_c_o_n, Technical Report TR 86-10,
  957.        Department of Computer Science, The University of Arizona.
  958.        1986.
  959.  
  960.  
  961.  
  962.  
  963.  
  964.  
  965.  
  966.  
  967.  
  968.  
  969.  
  970.  
  971.  
  972.  
  973.  
  974.  
  975.  
  976.  
  977.  
  978.  
  979.  
  980.  
  981.  
  982.  
  983.  
  984.  
  985.  
  986.  
  987.  
  988.                                  - 14 -
  989.  
  990.  
  991.